package com.mvc;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @Author: 柏竹
 * @Description: 映射器（处理大量网站与方法的对应关系）
 * @Date_Created_in: 2021-05-18 20:32
 * @Modified_By: Sans
 * @Project:
 */
public class HandlerMapping {
    // 每次请求都会在 Map进行查找对应方法进行处理
    private static Map<String, MVCMapping> data = new HashMap<>();
    
    /**
     * 获取网址对应的方法
     * @param uri
     * @return
     */
    public static MVCMapping get(String uri){
        return data.get(uri);
    }
    
    /**
     * 加载配置文件的方法
     * @param is
     */
    public static void load(InputStream is){
        
        Properties ppt = new Properties();
        try {
            ppt.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //读取配置文件，且进行遍历值
        Collection<Object> values = ppt.values();
        for (Object cla : values) {
            String className = (String)cla;
            //反射处理
            try {
                //加载 配置文件 值路径 指定的类
                Class c = Class.forName(className);
                // 实例类对象 （加载无参构造方法）
                Object obj = c.getConstructor().newInstance();
                
                //获取类的所有方法，且进行遍历
                Method[] methods = c.getMethods();
                for (Method method : methods) {
                    //获取方法中的注解
                    Annotation[] as = method.getAnnotations();
                    if (as != null) {
                        for (Annotation a : as) {
                            
                            //进行判断添加Map
                            if (a instanceof ResponseBody){
                                //该方法用于返回字符串
                                MVCMapping m = new MVCMapping(obj,method,ResponseType.TEXT);
                                Object o = data.put(((ResponseBody) a).value(),m);
                                if (o != null) {
                                    //    重复地址
                                    throw new RuntimeException("请求地址重复: "+((ResponseBody) a).value());
                                }
                            }else{
                                if (a instanceof ResponseView){
                                    //该方法用于返回页面
                                    MVCMapping m = new MVCMapping(obj,method,ResponseType.VIEW);
                                    Object o = data.put(((ResponseView) a).value(),m);
                                    if (o != null) {
                                        //    重复地址
                                        throw new RuntimeException("请求地址重复: "+((ResponseView) a).value());
                                    }
                                }
                            }
                        }
                    }
                    
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
        
    }
    
    /**
     * 映射对象（对象 == 方法）
     */
    public static class MVCMapping{
        private Object obj;
        private Method method;
        private ResponseType type;
    
        public MVCMapping() {
        }
    
        public MVCMapping(Object obj , Method method , ResponseType type) {
            this.obj = obj;
            this.method = method;
            this.type = type;
        }
    
        public Object getObj() {
            return obj;
        }
    
        public void setObj(Object obj) {
            this.obj = obj;
        }
    
        public Method getMethod() {
            return method;
        }
    
        public void setMethod(Method method) {
            this.method = method;
        }
    
        public ResponseType getType() {
            return type;
        }
    
        public void setType(ResponseType type) {
            this.type = type;
        }
    }
}
